home *** CD-ROM | disk | FTP | other *** search
- .include "pdlequ.h"
-
- *
- * DEFINITIONS
- *
- dmadata equ $ffff8604 ; /* dma control and status register */
- dmahigh equ $ffff8609 ; /* dma counter high */
- dmamid equ $ffff860b ; /* dma counter mid */
- dmalow equ $ffff860d ; /* dma counter low */
- gpip equ $fffffa01 ; /* mfp general purpose i/o */
- flock equ $43e ; /* dma lock semaphore */
- _hz_200 equ $4ba ; /* 200 hz timer */
-
- *
- * SLM804 print driver
- *
- CR equ $d
- LF equ $a
- FF equ $c
- ESC equ $1b
- DC2 equ $12
-
- .text
- ***************************************************************
- ***************************************************************
- ***************************************************************
- dumbentry:
- clr.l d0
- rts
-
- dc.l "PRNT"
- dc.w 201
-
- *
- * distribute the calls to the appropriate routines
- *
- slm804: move.l a0,table
- lsl.w #2,d0
- lea prntbl,a1
- move.l 0(a1,d0.w),a1
- jmp (a1)
-
-
- *
- * identify who I am, and set up who I like to speak to.
- *
- p_ident:
- move.l #driver,pdrvrnm(a0) ;pointer to string for driver name
- move.w #$8000+PRT+ASCENDING,device(a0)
- prtok: moveq #1,d0
- rrts: rts
- rterr: moveq #0,d1
- rts
- *
- * initialize the table of printer specific routines
- *
- p_init: clr.b pdl(a0) ;not a page description language driver
- move.b #1,pmult(a0) ;automatically print mulitiple copies?
- clr.b pman(a0) ;handle manual feed?
- move.b #PRT_BW,ptype(a0) ;printer type?
-
- *
- * pminlft and pmaxw must be evenly divisible by 16
- *
-
- move.w pdensity(a0),d0
- cmp.w #7,d0
- bcs pint1
- moveq #6,d0
- pint1: lsl.w #1,d0
-
- lea scl_tbl,a1
- move.w 0(a1,d0.w),scale
- lea xdpi_tbl,a1
- move.w 0(a1,d0.w),pxdpi(a0) ;x resolution
- lea ydpi_tbl,a1
- move.w 0(a1,d0.w),pydpi(a0) ;y resolution
- lea minl_tbl,a1
- move.w 0(a1,d0.w),pminlft(a0) ;pixels from the left
- lea minr_tbl,a1
- move.w 0(a1,d0.w),pminrht(a0) ;pixels from the right
- lea mint_tbl,a1
- move.w 0(a1,d0.w),pmintop(a0) ;pixels down from top
- lea minb_tbl,a1
- move.w 0(a1,d0.w),pminbot(a0) ;pixels up from bottom
- lea xover_tbl,a1
- move.w 0(a1,d0.w),pxover(a0) ;percentage of x overlap of dots
- lea yover_tbl,a1
- move.w 0(a1,d0.w),pyover(a0) ;percentage of y overlap of dots
- lea rowht_tbl,a1
- move.w 0(a1,d0.w),prowht(a0) ;rows height modula
-
- lsl.w #1,d0
- lea maxw_tbl,a1
- move.l 0(a1,d0.w),pmaxw(a0) ;maximum # pixels across
- lea maxh_tbl,a1
- move.l 0(a1,d0.w),pmaxh(a0) ;maximum # pixels down
- bra prtok
-
- *
- * going to begin printing a document
- *
- p_bgndoc:
- bra prtok
-
- *
- * about to start printing of a page
- *
- p_bgnpage:
- bra prtok
-
- *
- * about to print a new tile for the page
- *
- p_bgntile:
- bra prtok
-
- *
- * print a block to the printer
- *
- p_block:
- move.l m_alloc(a0),a0
- move.l #40000,d0
- moveq #0,d1
- jsr (a0)
- beq rrts
- move.l a0,p1handle
-
- move.l table,a0
- move.l m_alloc(a0),a0
- move.l #40000,d0
- moveq #0,d1
- jsr (a0)
- beq rrts
- move.l a0,p2handle
-
- move.l (a0),p2ptr
- move.l p1handle,a0
- move.l (a0),p1ptr
-
- move.l table,a0
- move.l pblockptr(a0),a1
- move.l (a1),_page_image
- move.l pblockw(a0),d0
- move.w d0,width ;width in bytes
- lsl.w #3,d0
- move.w d0,wbits ;width in bits
- move.l pblockh(a0),d0
- move.w d0,height ;height
- clr.l pblockh(a0)
-
- move.w pcopies(a0),tcopy
-
- block1: clr.l -(sp)
- move.w #$20,-(sp) ;set supervisor mode
- trap #1
- addq.l #6,sp
- move.l d0,stack
-
- jsr _print_page
-
- move.l stack,-(sp)
- move.w #$20,-(sp) ;return to user mode
- trap #1
- addq.l #6,sp
-
- subq.w #1,tcopy
- bhi block1
-
- move.l table,a1
- move.l m_delete(a1),a1
- move.l p1handle,a0
- jsr (a1)
-
- move.l table,a1
- move.l m_delete(a1),a1
- move.l p2handle,a0
- jsr (a1)
- bra prtok
-
- *
- * just finished describing current tile
- *
- p_endtile:
- bra prtok
-
- *
- * just finished describing all tiles for this page
- *
- p_endpage:
- bra prtok
-
- *
- * finished printing the document
- *
- p_enddoc:
- bra prtok
-
-
- ***************************************************
- *** original assumed 300x3180 ***
- *** ***
- ***************************************************
- *
- _print_page:
- move.l p1ptr,a0
- move.w #9999,d0
- pp1: clr.l (a0)+
- dbf d0,pp1
-
- move.l p2ptr,a0
- move.w #9999,d0
- pp2: clr.l (a0)+
- dbf d0,pp2
-
- *
- *
- *
- lea dmadata,a0 ;
- tas.b flock ; DMA channel currently in use?
- bne rterr ; --> yes, don't use it right now
-
- move.l #$e00000,cntrl
-
- *
- * INQUIRY - determine if the printer is happy, and what the controller # is
- *
- inquiry:
- move.w #$198,2(a0) ;DMA select?
- move.w #$88,2(a0) ;assert command signal
- move.l #$12008a,d0 ;MODE SENSE command byte 0
- or.l cntrl,d0
- jsr writcmnd ;to controller number (cntrl)
- bne badinq ;
- move.l #$00008a,d0 ;command byte 1
- jsr writcmnd ;
- bne badinq
- move.l #$00008a,d0 ;command byte 2
- jsr writcmnd ;
- bne badinq
- move.l #$00008a,d0 ;command byte 3
- jsr writcmnd ;
- bne badinq
- move.l #$00008a,d0 ;command byte 4
- jsr writcmnd ;
- bne badinq
- move.l #$800082,d0 ;command byte 5
- move.l d0,(a0) ;no acknowledge for byte 5
-
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- indel: cmp.l _hz_200,d1 ;
- bge indel ;
-
- bsr getstatus ;status byte- is everybody in?
- bne badinq
-
- lea identlist,a3 ;the parade is about to begin...
- bsr getstatus ;byte 0 - Device Type
- bne badinq
- move.b d0,(a3)+
- bsr getstatus ;byte 1
- bne badinq
- move.b d0,(a3)+
- bsr getstatus ;byte 2
- bne badinq
- move.b d0,(a3)+
- bsr getstatus ;byte 3
- bne badinq
- move.b d0,(a3)+
- bsr getstatus ;byte 4 - String Length
- bne badinq
- move.b d0,(a3)+
-
- moveq #0,d7
- move.b d0,d7
- bra inidl2
- inidl1: bsr getstatus ;get the next indentification list byte
- bne badinq
- move.b d0,(a3)+ ;save it in the table
- inidl2: dbf d7,inidl1 ;loop ListLength times
-
- lea identlist+5,a3
- cmp.b #"P",(a3)+
- bne badinq
- cmp.b #"A",(a3)+
- bne badinq
- cmp.b #"G",(a3)+
- bne badinq
- cmp.b #"E",(a3)+
- beq okinq
-
- badinq: move.w #$80,2(a0)
- sub.l #$200000,cntrl
- bcc inquiry
- bra prabrt
- *
- * MODE SENSE - get the current print parameters
- *
- okinq:
- move.w #$198,2(a0) ;DMA select?
- move.w #$88,2(a0) ;assert command signal
- move.l #$1a008a,d0 ;MODE SENSE command byte 0
- or.l cntrl,d0
- jsr writcmnd ;to controller number n
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 1
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 2
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 3
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 4
- jsr writcmnd ;
- bne prabrt ;
- move.l #$000082,d0 ;command byte 5
- move.l d0,(a0) ;no acknowledge for byte 5
-
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- msdel: cmp.l _hz_200,d1 ;
- bge msdel ;
-
- bsr getstatus ;status byte- is everybody in?
-
- lea paramlist,a3 ;the parade is about to begin...
- bsr getstatus ;List Length- num of bytes to follow
- move.b d0,(a3)+
- moveq #0,d7
- move.b d0,d7
- bra gtpml2
- gtpml1: bsr getstatus ;get the next parameter list byte
- move.b d0,(a3)+ ;save it in the table
- gtpml2: dbf d7,gtpml1 ;loop ListLength times
- move.w #$80,2(a0)
-
- move.b paramlist+3,owidth
- move.b paramlist+4,owidth+1
- move.w owidth,d0
- lsr.w #3,d0
- move.w d0,owidth
- mulu #128,d0
- move.l d0,olength
- add.l #32,olength
- divu #512,d0
- addq.w #1,d0
- swap d0
- move.w #$112,d0
- move.l d0,ocount
-
- *
- * setup the new parameters in paramlist to be sent
- *
- ; move.b wbits,paramlist+3
- ; move.b wbits+1,paramlist+4
- move.b height,paramlist+1
- move.b height+1,paramlist+2
-
- bclr #0,paramlist+9
- move.l table,a1
- tst.b pmanual(a1) ;handle manual feed?
- beq notmanual
- bset #0,paramlist+9 ;set manual feed bit
- notmanual:
-
- IF 0
- *
- * MODE SELECT - set the print parameters for the printer
- *
- move.w #$198,2(a0) ;DMA select?
- move.w #$88,2(a0) ;assert command signal
- move.l #$15008a,d0 ;MODE SELECT command byte 0
- or.l cntrl,d0
- jsr writcmnd ;to controller number n
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 1
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 2
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 3
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 4
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 5 (was $8a, might be $80 or $82)
- jsr writcmnd ;
- bne prabrt ;
-
- lea paramlist,a3 ;the parade is about to leave...
- moveq #0,d7
- move.b (a3)+,d7
- move.w d7,d0
- bra ptpml2
- ptpml1: bsr putstatus ;put the next parameter list byte
- bne prabrt ;
- move.b (a3)+,d0 ;get next byte from the table
- ptpml2: dbf d7,ptpml1 ;loop ListLength times
-
- bsr putstatus
- ; swap d0
- ; move.w #$0082,d0 ;was 82-last byte in extended command
- ; move.l d0,(a0) ;no acknowledge for last byte
- ; moveq.l #2,d1 ;~ 5 millisecond delay
- ; add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- ;sedel: cmp.l _hz_200,d1 ;
- ; bge sedel ;
-
- bsr getstatus ;status byte- is everybody in?
- move.w #$80,2(a0)
-
- ENDIF
-
- *
- * setup for first DMA cycle
- *
- move.w width,d0 ;copy width
- lsr.w #1,d0
- subq.w #1,d0
- move.w d0,cpwdth
-
- move.l _page_image,a2 ; /* load initial band base */
-
- move.l p1ptr,a5
- move.w #128,d4
- cpd1: move.l a2,a3 ;don't want to advance on second row
- move.l a5,a4
- move.w cpwdth,d3
- cpd2: move.w (a2)+,(a4)+
- dbf d3,cpd2
- add.w owidth,a5
- ; lea 300(a5),a5 ;skip white space (could precalc this)
- dbf d4,cpd1
- move.l a3,a2
-
- *
- * COMMAND PHASE
- *
- move.w #$198,2(a0) ;DMA select?
- move.w #$88,2(a0) ;assert command signal
- move.l #$0a008a,d0 ;PRINT command byte 0
- or.l cntrl,d0
- jsr writcmnd ;to controller number n
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 1
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 2
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 3
- jsr writcmnd ;
- bne prabrt ;
- move.l #$00008a,d0 ;command byte 4
- jsr writcmnd ;
- bne prabrt ;
- move.l #$000082,d0 ;command byte 5
- move.l d0,(a0) ;no acknowledge for byte 5
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- codel: cmp.l _hz_200,d1 ;
- bge codel ;
-
- *
- * DATA OUT PHASE
- *
- move.l p1ptr,d0
- move.l d0,-(sp)
- move.b 3(sp),dmalow ;initialize dma base address
- move.b 2(sp),dmamid
- move.b 1(sp),dmahigh
- addq.l #4,sp
-
- move.w #$192,2(a0) ;select sector count register
- move.l ocount,(a0) ;write sector count, start dma
-
- moveq #0,d7
- move.w height,d7
- add.w #127,d7
- divu #128,d7
- subq.w #1,d7
- bra bottom
-
- bdloop: add.l olength,d0 ;get final address to stop at
- move.w sr,d1 ; /* save status register */
- ori.w #$700,sr ; /* no interrupts, please */
-
- move.l p2ptr,a5 ; swap p1ptr <-> p2ptr
- move.l p1ptr,p2ptr
- move.l a5,p1ptr
-
- move.w #128,d4
- cpd3: move.l a2,a3 ;don't want to advance on second row
- move.l a5,a4
- move.w cpwdth,d3
- cpd4: move.w (a2)+,(a4)+
- dbf d3,cpd4
- add.w owidth,a5
- ; lea 300(a5),a5 ;skip white space (could precalc this)
- dbf d4,cpd3
- move.l a3,a2
-
- bdwait: btst.b #5,gpip ;check for premature status phase
- beq fuckoff ;stwait ;abort and get status byte
- movep.w 7(a0),d2 ;get current DMA mid and low
- cmp.w d2,d0 ;compare to final address
- bne bdwait ;not there yet?
-
- move.l p1ptr,d0
- addq.l #2,d0 ;compensate for FIFO
- move.l d0,-(sp)
- move.b 3(sp),dmalow ;reinitialize DMA base address
- move.b 2(sp),dmamid ;
- move.b 1(sp),dmahigh ;
- addq.l #4,sp ;
- move.w #$92,2(a0) ;reset FIFO
- move.w #$192,2(a0) ;
- move.l ocount,(a0) ;reload sector count register
-
- move.w d1,sr ;restore status register
- bottom: dbra d7,bdloop ;more bands?
-
- *
- * STATUS PHASE
- *
- fuckoff:
-
- stwait: btst.b #5,gpip ;wait for status byte
- bne stwait ;
- stbyte: move.w d1,sr ;restore status register
- move.w #$8a,2(a0) ;select status register
- move.w (a0),d0 ;read status byte
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- stdel: cmp.l _hz_200,d1 ;
- bge stdel ;
- bra prexit ;return status byte
- prabrt: moveq.l #-1,d0 ;return error flag
- prexit: move.w #$80,2(a0)
- sf flock ;unlock dma channel
- rts ;
-
-
-
- ***************************************************
- *** ***
- ***************************************************
- getstatus:
- moveq.l #100,d1 ;500 millisecond timeout
- add.l _hz_200,d1 ;
- gstime: btst.b #5,gpip ;
- beq gsbyte ;command byte acknowledged
- cmp.l _hz_200,d1 ;
- bge gstime ;
- moveq.l #-1,d1 ;timeout - set error flag
- rts ;
-
- gsbyte: move.w #$8a,2(a0) ;select status register
- move.w (a0),d0 ;read status byte
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- gsdel: cmp.l _hz_200,d1 ;
- bge gsdel ;
- moveq #0,d1
- rts
-
-
- ***************************************************
- *** ***
- ***************************************************
- *
- * WRITCMND
- * Write command byte to DMA controller.
- *
- * Inputs: d0.L = Data/control words
- * a0 = Pointer to DMA controller (ff8604)
- * Outputs: EQ = Successful command write
- * NE = Error occurred
- * Modified: d1
- *
- putstatus:
- swap d0
- move.w #$8a,d0
-
- writcmnd:
- move.l d0,(a0) ;write command byte
- moveq.l #2,d1 ;~ 5 millisecond delay
- add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
- wrdel: cmp.l _hz_200,d1 ;
- bge wrdel ;
- moveq.l #40,d1 ;200 millisecond timeout
- add.l _hz_200,d1 ;
- writlp: btst.b #5,gpip ;
- beq writok ;command byte acknowledged
- cmp.l _hz_200,d1 ;
- bge writlp ;
- moveq.l #-1,d1 ;timeout - set error flag
- writok: rts ;
-
-
- ***********************************
- *** ***
- ***********************************
- .data
-
- prntbl: dc.l prtok,prtok,prtok,prtok,p_init
- dc.l p_bgndoc,p_bgnpage,p_bgntile
- dc.l p_block
- dc.l p_endtile,p_endpage,p_enddoc
- dc.l prtok,p_ident
-
- scl_tbl: dc.w 1,1,1,1,1,1,1
- xdpi_tbl: dc.w 300,300,300,300,300,300,300
- ydpi_tbl: dc.w 300,300,300,300,300,300,300
- minl_tbl: dc.w 75,75,75,75,75,75,75
- minr_tbl: dc.w 75,75,75,75,75,75,75
- mint_tbl: dc.w 56,56,56,56,56,56,56
- minb_tbl: dc.w 56,56,56,56,56,56,56
- maxw_tbl: dc.l 2400,2400,2400,2400,2400,2400,2400
- maxh_tbl: dc.l 0,0,0,0,0,0,0
- xover_tbl: dc.w 0,0,0,0,0,0,0
- yover_tbl: dc.w 0,0,0,0,0,0,0
- rowht_tbl: dc.w 1,1,1,1,1,1,1
-
- driver: dc.b "Atari SLM804 v2.0.3-3",0
-
- .bss
- temp: ds.l 1
- tcopy: ds.w 1
- scale: ds.w 1
- _page_image: ds.l 1
- stack: ds.l 1
- height: ds.w 1
- width: ds.w 1
- wbits: ds.w 1
- owidth: ds.w 1
- olength: ds.l 1
- ocount: ds.l 1
-
- table: ds.l 1
- cpwdth: ds.w 1
- cntrl: ds.l 1
-
- paramlist: ds.b 50
- identlist: ds.b 50
-
- p1handle: ds.l 1
- p1ptr: ds.l 1
- p2handle: ds.l 1
- p2ptr: ds.l 1
-
- ;
- ; 2.0.1 - added support for manual feed
- ; 2.0.2 - changed timing
- ; added support for variable length bitmaps
- ; removed 75,100,& 150 dpi options (they didn't do anything)
-